﻿using System;
using System.Data;
using System.Configuration;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;
using HRProject.Code.DTO;
using System.Collections.Generic;

namespace HRProject.Code.DAO
{
    public class DepartmentDAO : BaseDAO
    {
        public DepartmentDAO()
            : base ()
        {
        }

        public BLDepartment getRootDepartment()
        {
            List<BLDepartment> departments = select();
            BLDepartment root = arrangeDepartment(departments);
            return root;
        }

        private List<BLDepartment> select()
        {
            List<BLDepartment> result = new List<BLDepartment>();
            List<BaseCondition> condition = new List<BaseCondition>();
            condition.Add(new BaseCondition("@departmentId", Guid.Empty, ParameterDirection.Input));
            condition.Add(new BaseCondition("@name", string.Empty, ParameterDirection.Input));
            condition.Add(new BaseCondition("@parentDepartmentId", Guid.Empty, ParameterDirection.Input));
            DataTable data = select("usp_searchDepartments", condition);
            for (int i = 0; i < data.Rows.Count; i++)
            {
                BLDepartment department = new BLDepartment();
                department.Id = (Guid)data.Rows[i]["DepartmentId"];
                department.Name = (string)data.Rows[i]["DepartmentName"];
                department.IconUrl = (string)data.Rows[i]["IconUrl"];
                department.Description = (string)data.Rows[i]["Description"];
                department.Parent = new BLDepartment();
                department.Parent.Id = (Guid)data.Rows[i]["ParentDepartmentId"];
                department.DataSignature = (long)data.Rows[i]["DataSignature"];
                department.CreateDate = (DateTime)data.Rows[i]["CreateDate"];
                department.CreateUserId = (Guid)data.Rows[i]["CreateUserId"];
                department.UpdateDate = (DateTime)data.Rows[i]["UpdateDate"];
                department.UpdateUserId = (Guid)data.Rows[i]["UpdateUserId"];
                result.Add(department);
            }
            return result;
        }

        public List<BLDepartment> search(BLDepartment filterDepartment)
        {
            List<BLDepartment> result = new List<BLDepartment>();
            List<BaseCondition> condition = new List<BaseCondition>();
            condition.Add(new BaseCondition("@departmentId", filterDepartment.Id,ParameterDirection.Input));
            condition.Add(new BaseCondition("@name", filterDepartment.Name,ParameterDirection.Input));
            condition.Add(new BaseCondition("@parentDepartmentId", filterDepartment.Parent.Id,ParameterDirection.Input));
            DataTable data = select("usp_searchDepartments", condition);
            for (int i = 0; i < data.Rows.Count; i++)
            {
                BLDepartment department = new BLDepartment();
                department.Id = (Guid)data.Rows[i]["DepartmentId"];
                department.Name = (string)data.Rows[i]["DepartmentName"];
                department.IconUrl = (string)data.Rows[i]["IconUrl"];
                department.Description = (string)data.Rows[i]["Description"];
                department.Parent = new BLDepartment();
                department.Parent.Id = (Guid)data.Rows[i]["ParentDepartmentId"];
                department.Parent.Name = (string)data.Rows[i]["ParentDepartmentName"];
                department.DataSignature = (long)data.Rows[i]["DataSignature"];
                department.CreateDate = (DateTime)data.Rows[i]["CreateDate"];
                department.CreateUserId = (Guid)data.Rows[i]["CreateUserId"];
                department.UpdateDate = (DateTime)data.Rows[i]["UpdateDate"];
                department.UpdateUserId = (Guid)data.Rows[i]["UpdateUserId"];
                result.Add(department);
            }
            return result;
        }

        private BLDepartment arrangeDepartment(List<BLDepartment> departments)
        {
            BLDepartment result = new BLDepartment();
            result.Name = "Company";
            foreach (BLDepartment dept in departments)
            {
                bind(result, dept);
            }
            return result;
        }

        private bool bind(BLDepartment ancestor, BLDepartment dept)
        {
            if (ancestor.Id == dept.Parent.Id)
            {
                int index = 0;
                for (int i = 0; i < ancestor.Children.Count; i++)
                {
                    if (dept.Name.ToLower().CompareTo(ancestor.Children[i].Name.ToLower()) > 0)
                    {
                        index = i+1;
                        break;
                    }
                }
                ancestor.Children.Insert(index, dept);
                dept.Parent = ancestor;
                return true;
            }
            foreach (BLDepartment child in ancestor.Children)
            {
                if (bind(child, dept))
                {
                    return true;
                }
            }
            return false;
        }

        public int insert(BLDepartment department)
        {
            List<BaseCondition> condition = new List<BaseCondition>();
            int errorCode = 0;
            condition.Add(new BaseCondition("@id", Guid.NewGuid(), ParameterDirection.Input));
            condition.Add(new BaseCondition("@name",department.Name,ParameterDirection.Input));
            condition.Add(new BaseCondition("@description", department.Description, ParameterDirection.Input));
            condition.Add(new BaseCondition("@iconUrl", department.IconUrl, ParameterDirection.Input));
            condition.Add(new BaseCondition("@parentDepartmentId", department.Parent.Id, ParameterDirection.Input));
            condition.Add(new BaseCondition("@createUserId", Membership.GetUser().ProviderUserKey.ToString(),ParameterDirection.Input));
            condition.Add(new BaseCondition("@dataSignature",department.DataSignature,ParameterDirection.Input));
            condition.Add(new BaseCondition("@errorCode",errorCode,ParameterDirection.Output));
            int result = update("usp_addDepartment", condition);
            return result;
        }

        public int update(BLDepartment department)
        {
            List<BaseCondition> condition = new List<BaseCondition>();
            int errorCode = 0;
            condition.Add(new BaseCondition("@id", department.Id, ParameterDirection.Input));
            condition.Add(new BaseCondition("@name", department.Name, ParameterDirection.Input));
            condition.Add(new BaseCondition("@description", department.Description, ParameterDirection.Input));
            condition.Add(new BaseCondition("@iconUrl", department.IconUrl, ParameterDirection.Input));
            condition.Add(new BaseCondition("@updateUserId", Membership.GetUser().ProviderUserKey.ToString(), ParameterDirection.Input));
            condition.Add(new BaseCondition("@dataSignature", department.DataSignature, ParameterDirection.Input));
            condition.Add(new BaseCondition("@errorCode", errorCode, ParameterDirection.Output));
            int result = update("usp_updateDepartment", condition);
            return result;
        }

        public int delete(BLDepartment department)
        {
            List<BaseCondition> condition = new List<BaseCondition>();
            int errorCode = 0;
            condition.Add(new BaseCondition("@id", department.Id, ParameterDirection.Input));
            condition.Add(new BaseCondition("@updateUserId", Membership.GetUser().ProviderUserKey.ToString(), ParameterDirection.Input));
            condition.Add(new BaseCondition("@dataSignature", department.DataSignature, ParameterDirection.Input));
            condition.Add(new BaseCondition("@errorCode", errorCode, ParameterDirection.Output));
            int result = update("usp_deleteDepartment", condition);
            return result;
        }
    }
}
